// ==UserScript==
// @name         华为商城自动抢购
// @namespace    Gee.J
// @version      1.0
// @description  华为商城自动抢购抢购自动提交订单
// @author       Gee.J
// @match        https://www.vmall.com/product/*
// @match        https://www.vmall.com/order/nowConfirmcart*
// @match        https://www.vmall.com/cart2*
// @match        https://m.vmall.com/order/confirm*
// @match        https://buy.vmall.com/submit_order.html*
// @match        https://id1.cloud.huawei.com/CAS/portal/loginAuth.html*
// @connect      buy.vmall.com
// @grant        GM_xmlhttpRequest
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// @require      http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @require      https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
// ==/UserScript==

(function() {
	'use strict';
    let activityId = 0;
    let sbomCode = 0;
	let startTime = 0; // 活动开始时间
	let queueDelay = 0; // 排队延迟
    const queueDelayDefault = 1;
    let queueFrequency = 0; // 排队频率
    const queueFrequencyDefault = 5;
    let queueCount = 0; // 排队总数
    const queueCountDefault = 25;
    let queueSi = 0; // 定时器id
    let vdInput;// 排队启动延迟input
    let vfInput;// 排队频率input
    let vcInput;// 排队总数input
    let vsButton;// 按钮
	// 如果是结算页，自动提交订单
	if (window.location.href.indexOf('https://buy.vmall.com/submit_order.html') !== -1) {
		ec.order.checkOrder.doSubmit();
	}
	if (window.location.href.indexOf('https://www.vmall.com/order/nowConfirmcart') !== -1) {
		ec.order.submit();
	}

	// 如果是商品详情页
	if (window.location.href.indexOf("https://www.vmall.com/product") != -1) {
		// 检测是否已登录
		if (rush.account.isLogin()) {
            // 加载UI框
            initBox();
		} else {
			// 跳转登录页面
			rush.business.doGoLogin();
		}
	}

	// 初始化UI框
	function initBox() {
		const myCon = `<div id="VmallOperatorWin"><dl><dt>&nbsp;</dt></dl><dd><a style="padding:5px 28px;background:green;color:#fff;cursor:pointer;font-size:1.5em" id="VowStart">开始倒计时</a><dd> &nbsp;&nbsp;</dd><dd></dl><dl id="VowPm"><dd> 启动延迟&nbsp;&nbsp;<input type="number" id="VowDelay" style="width:55px;" value="0"/>ms&nbsp;&nbsp;间隔&nbsp;&nbsp;<input type="number" id="VowFrequency" style="width:55px;" value="5"/>ms&nbsp;&nbsp;总数&nbsp;&nbsp;<input type="number" id="VowCount" style="width:55px;" value="50"/>次</dd></dl><dl></dl><dd></dl></div>`;
		$('#product-operation').append(myCon);
        queueFrequency = GM_getValue("queueFrequency", queueFrequencyDefault);
        queueCount = GM_getValue("queueCount", queueCountDefault);
        queueDelay = GM_getValue("queueDelay", queueDelayDefault);
        // 排队启动延迟赋值
        vdInput = document.getElementById('VowDelay');
        vdInput.value = queueDelay;
        // 排队频率赋值
        vfInput = document.getElementById('VowFrequency');
        vfInput.value = queueFrequency;
        // 排队总数赋值
        vcInput = document.getElementById('VowCount');
        vcInput.value = queueCount;
        // 按钮
        vsButton = document.getElementById('VowStart');
        vsButton.addEventListener('click', function() {
            // 定时器未开启
            if(queueSi==0) {
                vsButton.text = '正在倒计时';
                startAction(vsButton);
            } else {
                vsButton.text = '开始倒计时';
                clearInterval(queueSi);
                queueSi = 0;
            }
        });
	}

    // 开始倒计时
    function startAction(){
        // 获取参数
        queueFrequency = parseInt(vfInput.value);
        if (queueFrequency<=0) queueFrequency = queueFrequencyDefault;
        queueCount = parseInt(vcInput.value);
        if (queueCount<=0) queueCount = queueCountDefault;
        queueDelay = parseInt(vdInput.value);
        if (queueDelay<=0) queueDelay = queueDelayDefault;
        // 缓存参数
        GM_setValue("queueFrequency", queueFrequency);
        GM_setValue("queueCount", queueCount);
        GM_setValue("queueDelay", queueDelay);
        // 获取活动信息
		sbomCode = ec.product.getSkuInfo(ec.product.getSku()).code;
        console.log("sbomCode: " + sbomCode);
        // 请求活动信息
        GM_xmlhttpRequest({
			method: 'GET',
			url: "https://buy.vmall.com/queryRushbuyInfo.json?sbomCodes=" + sbomCode + "&portal=1&t=" + new Date().getTime(),
			onload: function(responseDetails) {
				if (responseDetails.status === 200) {
					const res = JSON.parse(responseDetails.responseText);
                    //console.log(res);
					startTime = res.skuRushBuyInfoList[0].startTime;
                    activityId = res.skuRushBuyInfoList[0].activityId;
					console.log("ActivityId: " + activityId);
					console.log("Start Time: " + dateFormat("YYYY-mm-dd HH:MM:SS", new Date(startTime)));
                    // 开始执行
                    queueSi = setInterval(function() {
                        const nowTime = rush.business.getSysDate().getTime();
                        if (nowTime > startTime) {
                            clearInterval(queueSi);
                            queueSi = 0;
                            // 开始抢购模式
                            startRushMode();
                        } else {
                            vsButton.text = `正在倒计时（${getDistanceSpecifiedTime(startTime, nowTime)}）`;
                        }
                    }, 10);
				}
			}
		});
    }

    // 获取队列rp参数化
    function getQueueRp() {
        return new Promise(function(resolve, reject) {
            GM_xmlhttpRequest({
                method: 'GET',
                url: "https://buy.vmall.com/joinQueue.json?t="+new Date().getTime() +"&activityID="+activityId+"&sbomCode="+ sbomCode + "&num=1",
                onload: function(responseDetails) {
                    if (responseDetails.status === 200) {
                        const res = JSON.parse(responseDetails.responseText);
                        if (res.success) {
                            resolve(res.data.rp);
                        } else {
                            reject(res.code);
                        }
                    }
                }
            });
        });
    }

    // 抢购模式
    async function startRushMode() {
        try{
            // 尝试加入队列
            const rp = await getQueueRp();
            joinQueue(rp);
            singleTaskAdvancedMode();
        } catch(e) {
            // 入队失败
            if (e == "880004") {
                // 活动未开始，等一会再试
                console.log("活动未开始");
                vsButton.text = '等待活动开始';
                setTimeout(startRushMode, queueDelay);
            } else if (e == "880006") {
                // 活动已结束
                console.log("活动已结束");
                vsButton.text = '活动已结束';
                clearInterval(queueSi);
                queueSi = 0;
            } else {
                vsButton.text = '错误代码：'+e;
                clearInterval(queueSi);
                queueSi = 0;
            }
        }
    }

    function joinQueue(rp) {
        let url = "https://buy.vmall.com/queue.html?"+(new Date).getTime();
        url += "&sbom="+sbomCode;
        url += "&activityID="+activityId;
        url += "&r="+rp;
        url += "&portal=1&fUrl=https%3A%2F%2Fwww.vmall.com%2Forder%2FnowConfirmcart%3FrushActivityId%3D"+activityId;
        url += "%26buttonMode%3D"+ec.product.getSkuInfo(ec.product.getSku()).buttonMode;
        url += "%26sbomCode%3D"+sbomCode;
        url += "%26num%3D1";
        url += "%26orderReqJson%3D"+rush.business.getNormalParams4RushBuy2ConfirmOrder().orderReqJson;
        url += "%26state%3D0";
        rush.activity.popOutQueue(url);
    }

    // 高级抢购单任务
    function singleTaskAdvancedMode() {
        let i = 0;
        queueSi = setInterval(function() {
            rush.business.doGoRushBuy2(this);
            if (i > queueCount) {
                clearInterval(queueSi);
                queueSi = 0;
            } else {
                i++;
            }
        }, queueFrequency);
    }

    // 抢购倒计时对比
    function getDistanceSpecifiedTime(dateTime, currentTime) {
            // 指定日期和时间
            var EndTime = new Date(dateTime).getTime();
            var t = EndTime - currentTime
            var d = Math.floor(t / 1000 / 60 / 60 / 24).toString().padStart(2, '0');
            var h = Math.floor(t / 1000 / 60 / 60 % 24).toString().padStart(2, '0');
            var m = Math.floor(t / 1000 / 60 % 60).toString().padStart(2, '0');
            var s = Math.floor(t / 1000 % 60).toString().padStart(2, '0');
            return `${d}天 ${h}:${m}:${s}`;
        }

	// 时间格式化
	function dateFormat(fmt, date) {
		let ret;
		let opt = {
			"Y+": date.getFullYear().toString().padStart(4, '0'),
			"m+": (date.getMonth() + 1).toString().padStart(2, '0'),
			"d+": date.getDate().toString().padStart(2, '0'),
			"H+": date.getHours().toString().padStart(2, '0'),
			"M+": date.getMinutes().toString().padStart(2, '0'),
			"S+": date.getSeconds().toString().padStart(2, '0')
		};

		if (/(Y+)/.exec(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
		for (let k in opt) {
			ret = new RegExp("(" + k + ")").exec(fmt);
			if (ret) {
				fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (("00" + opt[k]).substr(("" + opt[k]).length)));
			};
		};

		return fmt;
	}
})();